package com.photoeditor.demo.util;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RSRuntimeException;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.widget.ImageView;

import androidx.annotation.RequiresApi;

import com.common.base.ComponentContext;

/**
 * Created by Lai on 2018/11/8 0008.
 */
public class BlurUtil {

    /**
     * 先缩小图片，然后再模糊
     */
    public static Bitmap blur2(Context context, Bitmap orgBitmap, int radius, int rate) throws RSRuntimeException {
        int targetWidth =  orgBitmap.getWidth()/rate;
        int targetHeidht = orgBitmap.getHeight()/rate;
        Bitmap  blurredBitmap = Bitmap.createBitmap(targetWidth, targetHeidht, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(blurredBitmap);
        canvas.drawBitmap(orgBitmap, null, new RectF(0, 0, targetWidth, targetHeidht), null);

        return blur(context, blurredBitmap, radius);
    }

    public static Bitmap drawDarkCover(Bitmap orgBitmap) {
        Canvas canvas = new Canvas(orgBitmap);
        canvas.drawBitmap(orgBitmap, 0, 0, null);
        canvas.drawARGB(76, 137, 137, 137);
        return orgBitmap;
    }

    /**
     * 模糊处理后，在上面加一层暗色蒙板
     */
    public static Bitmap darkBlur(Context context, Bitmap orgBitmap, int radius) throws RSRuntimeException {
        Bitmap blurredBitmap = blur2(context, orgBitmap, 2, radius);
        Canvas canvas = new Canvas(blurredBitmap);
        canvas.drawARGB(76, 137, 137, 137);
        return blurredBitmap;
    }

    public static Bitmap blur(Context context, Bitmap blurredBitmap, int radius) throws RSRuntimeException {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            try {

                RenderScript rs = RenderScript.create(context);
                Allocation input = Allocation.createFromBitmap(rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_NONE,
                        Allocation.USAGE_SCRIPT);
                Allocation output = Allocation.createTyped(rs, input.getType());
                ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

                blur.setInput(input);
                blur.setRadius(radius);
                blur.forEach(output);
                output.copyTo(blurredBitmap);
                rs.destroy();
            } catch (RSRuntimeException e) {
                blurredBitmap = FastBlur.doBlur(blurredBitmap, radius, true);
            }
        } else {
            blurredBitmap = FastBlur.doBlur(blurredBitmap, radius, true);
        }
        return blurredBitmap;
    }

    public static void blurViewAndApply(final View view, final ImageView imageView) {
        if (view == null || imageView == null) {
            return;
        }
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                view.setDrawingCacheEnabled(true);
                view.buildDrawingCache();
                Bitmap ret = Bitmap.createBitmap(view.getDrawingCache());
                view.destroyDrawingCache();
                view.setDrawingCacheEnabled(false);
                Bitmap blur = BlurUtil.blur(ComponentContext.getContext(), ret, 25);
                imageView.setImageBitmap(blur);
                view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });
    }



    //原face页的模糊效果不明显，新增的模糊逻辑
//    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public static void applyBlur(Activity activity, View vipView) {
        if (vipView.getVisibility() == View.VISIBLE) {
            vipView.setVisibility(View.INVISIBLE);//自身的view不要一起截屏
        }

        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache(true);
        /**
         * 获取当前窗口快照，相当于截屏
         */
        Bitmap bmp1 = view.getDrawingCache();
//        final Bitmap bmp1 = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
        int height = getOtherHeight(activity);
        /**
         * 除去状态栏和标题栏
         */
        Bitmap bmp2 = Bitmap.createBitmap(bmp1, 0, height,bmp1.getWidth(), bmp1.getHeight() - height);
        blur(activity, bmp2, vipView);

        if (vipView.getVisibility() == View.INVISIBLE) {
            vipView.setVisibility(View.VISIBLE);//自身的view不要一起截屏
        }
    }

//    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    private static void blur(Activity activity, Bitmap bkg, View view) {
        long startMs = System.currentTimeMillis();
        float scaleFactor = 5;//图片缩放比例；
        float radius = 10;//模糊程度

        Bitmap overlay = Bitmap.createBitmap(
                (int) (view.getMeasuredWidth() / scaleFactor),
                (int) (view.getMeasuredHeight() / scaleFactor),
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(overlay);
        canvas.translate(-view.getLeft() / scaleFactor, -view.getTop()/ scaleFactor);
        canvas.scale(1 / scaleFactor, 1 / scaleFactor);
        Paint paint = new Paint();
        paint.setFlags(Paint.FILTER_BITMAP_FLAG);
        canvas.drawBitmap(bkg, 0, 0, paint);


        overlay = FastBlur.doBlur(overlay, (int) radius, true);
        view.setBackground(new BitmapDrawable(activity.getResources(), overlay));
        /**
         * 打印高斯模糊处理时间，如果时间大约16ms，用户就能感到到卡顿，时间越长卡顿越明显，如果对模糊完图片要求不高，可是将scaleFactor设置大一些。
         */
//        Log.i("jerome", "blur time:" + (System.currentTimeMillis() - startMs));
    }

    /**
     * 获取系统状态栏和软件标题栏，部分软件没有标题栏，看自己软件的配置；
     * @return
     */
    private static int getOtherHeight(Activity activity) {
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;
        int contentTop = activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
        int titleBarHeight = contentTop - statusBarHeight;
        return statusBarHeight + titleBarHeight;
    }

}
